package com.atguigu.srb.servicesms.service.impl;

import com.alibaba.fastjson.JSON;
import com.atguigu.srb.base.util.HttpUtils;
import com.atguigu.srb.common.exception.Assert;
import com.atguigu.srb.common.result.ResponseEnum;
import com.atguigu.srb.common.result.Result;
import com.atguigu.srb.common.util.RandomUtils;
import com.atguigu.srb.common.util.RegexValidateUtils;
import com.atguigu.srb.servicesms.client.CoreClient;
import com.atguigu.srb.servicesms.pojo.Message;
import com.atguigu.srb.servicesms.pojo.SmsProperties;
import com.atguigu.srb.servicesms.service.SmsService;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.sql.Array;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * ClassName: SmsServiceImpl
 * Package: com.atguigu.srb.servicesms.service.impl
 * Description:
 *
 * @Author 王晓龙
 * @Create 2023/3/29 21:06
 * @Version 1.0
 */
@Service
@EnableConfigurationProperties(SmsProperties.class)
public class SmsServiceImpl implements SmsService {
    @Resource
    StringRedisTemplate stringRedisTemplate;
    @Resource
    CoreClient coreClient;

    @Override
    public String sendSms(Message message) {
        //1. 手机号码格式校验：正则表达式
        String mobile = message.getMobile();
        Integer type = message.getType();

        Assert.assertTrue(RegexValidateUtils.checkCellphone(mobile), ResponseEnum.MOBILE_ERROR);
        //判断手机号是否已经注册
        if (type==1){
            String msg = coreClient.isUsed(mobile).getMessage();
            if ("true".equals(msg)){
                return "手机号已被注册";
            }
        }
        //2. 5分钟内不能重复获取 key
        String timeLimitKey = "sms:limit:" + type + ":" + mobile;
        Assert.assertNotTrue(stringRedisTemplate.hasKey(timeLimitKey), ResponseEnum.ALIYUN_SMS_LIMIT_CONTROL_ERROR);
        //2. 一天内只能获取5条 key
        String countLimitKey = "sms:count:" + type + ":" + mobile;
        if (stringRedisTemplate.hasKey(countLimitKey)){
            //存在发送短信的次数：获取次数
            String countStr = stringRedisTemplate.opsForValue().get(countLimitKey);
            Assert.assertNotTrue(Integer.parseInt(countStr)>=5, ResponseEnum.ALIYUN_SMS_LIMIT_CONTROL_ERROR);
        }else{
            //countLimitKey 次数数据不存在 初始化0，并设置过期时间
            stringRedisTemplate.opsForValue().set(countLimitKey, "0", 24, TimeUnit.HOURS);
        }
        //3. 生成验证码发送短信
        String code  = RandomUtils.getFourBitRandom();
        message.setCode(code);
        sendMessage(message);
        //4、更新手机号码获取验证码的频率,缓存验证码
        stringRedisTemplate.opsForValue().set("sms:code:" + type + ":" + mobile, code, 5, TimeUnit.MINUTES);
        //打印出存在缓存的k-v数据
        System.out.println("key->" + "sms:code:" + type + ":" + mobile + "; value->" + code);
        //更新验证码发送的次数:
        // 如果手机号第一次获取验证码 increment次数默认为0+1
        stringRedisTemplate.opsForValue().increment(countLimitKey);
        stringRedisTemplate.opsForValue().set(timeLimitKey, "1", 5, TimeUnit.MINUTES);
        return null;
    }

    public void sendMessage(Message message){
        String host = "https://dfsns.market.alicloudapi.com";
        String path = "/data/send_sms";
        String method = "POST";
        String appcode = "77e755b9b59f47ebb22908b4fa415d2d";
        Map<String, String> headers = new HashMap<String, String>();
        headers.put("Authorization", "APPCODE " + appcode);
        headers.put("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
        Map<String, String> querys = new HashMap<String, String>();
        Map<String, String> bodys = new HashMap<String, String>();
        bodys.put("content", "code:"+message.getCode());
        bodys.put("phone_number", message.getMobile());
        bodys.put("template_id", "CST_ptdie100");
        try {
            HttpResponse response = HttpUtils.doPost(host, path, method, headers, querys, bodys);
            String resultJson = EntityUtils.toString(response.getEntity(), "UTF-8");
            Map map = JSON.parseObject(resultJson, Map.class);
            String resultCode = map.get("status").toString();
            if ("OK".equals(resultCode)){
                System.out.println("信息发送成功：" + resultJson);
            }else{
                System.out.println("短信发送失败，原因：" + resultJson);
            }
//            System.out.println(response.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}